home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr47
/
wasm223.zip
/
BASE.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-05-04
|
29KB
|
923 lines
;********************************************************
; BASE -- By Eric Tauck
;
; This program pops up a window and allows numbers and
; characters to be entered and their hexadecimal and
; decimal equivalents displayed. Use the up/down arrow
; or tab keys to switch between input fields. Press ESC
; to exit and restore the screen.
;
; Base can be used as a run-it-when-you-want-it utility
; or installed as a TSR. Base is invoked as follows:
;
; BASE run Base without installing as TSR
; BASE /R install Base as TSR
; BASE /U uninstall Base as TSR
;
; Base may not work properly on some adapters if the
; active video page is not zero. See the note below on
; the -p switch when using Base with Brief.
;
; This program uses the WASM library files.
;
;--------------------------------------------------------
;
; You can call Base directly from the editor Brief
; (without making Base a TSR) with the following Brief
; macro:
;
; base()
; {
; dos ("base.com >& nul", 0);
; }
;
; Base must be somewhere on the current path. Base
; will not work properly with Brief on some adapters
; unless the -p switch is used when starting Brief. The
; -p switch forces Brief to use video page zero.
INCLUDE 'library\case1.asm'
INCLUDE 'library\convert.asm'
INCLUDE 'library\draw1.asm'
INCLUDE 'library\shift.asm'
INCLUDE 'library\tsr1.asm'
INCLUDE 'library\tsr2.asm'
INCLUDE 'library\tsr3.asm'
INCLUDE 'library\video1.asm'
INCLUDE 'library\video3.asm'
INCLUDE 'library\video4.asm'
INCLUDE 'library\video5.asm'
INCLUDE 'library\video6.asm'
jmp install
COLS EQU 14 ;columns used
ROWS EQU 10 ;rows used
;--- screen attributes
ATR1_BW EQU (WHITE * 16) OR BLACK ;border color
ATR2_BW EQU (WHITE * 16) OR BLACK ;blank area color
ATR3_BW EQU (WHITE * 16) OR BLACK ;text color
ATR4_BW EQU (BLACK * 16) OR WHITE OR BOLD ;number color
ATR5_BW EQU (BLACK * 16) OR WHITE OR BOLD ;input color
ATR6_BW EQU (WHITE * 16) OR BLACK ;title color
ATR1_COL EQU (BLUE * 16) OR CYAN OR BOLD ;border color
ATR2_COL EQU (BLUE * 16) OR WHITE OR BOLD ;blank area color
ATR3_COL EQU (BLUE * 16) OR WHITE OR BOLD ;text color
ATR4_COL EQU (CYAN * 16) OR BROWN OR BOLD ;number color
ATR5_COL EQU (RED * 16) OR BROWN OR BOLD ;input color
ATR6_COL EQU (BLUE * 16) OR GREEN OR BOLD ;title color
atr1 DB ATR1_BW ;
atr2 DB ATR2_BW ;-- these are copied over by
atr3 DB ATR3_BW ; the 'colors' array below
atr4 DB ATR4_BW ; if a color video mode or
atr5 DB ATR5_BW ; adapter is detected
atr6 DB ATR6_BW ;
;--- input field array
input DW 0
inputs DW OFFSET HEX_inp, OFFSET DEC_inp, OFFSET CHR_inp
;--- layout of input record
adjust EQU 0 ;case adjustment
valid EQU 2 ;validate input
recalc EQU 4 ;recalculate total
update EQU 6 ;update input string
locate EQU 8 ;location
inpbas EQU 10 ;input base
inpmax EQU 12 ;input maximum
inplen EQU 14 ;input length
inpptr EQU 16 ;input pointer
;--- hex input data
HEX_X EQU 2
HEX_Y EQU 2
HEX_MAX EQU 8
HEX_inp LABEL WORD
DW OFFSET HEX_adj ;case adjustment
DW OFFSET HEX_val ;validate input
DW OFFSET HEX_rec ;recalculate total
DW OFFSET HEX_upd ;update input string
DW (HEX_Y * 256) + HEX_X ;location
DW OFFSET HEX_base ;input base
DW HEX_MAX ;input maximum
DW ? ;input length
DW ? ;input pointer
;--- decimal input data
DEC_X EQU 2
DEC_Y EQU 5
DEC_MAX EQU 10
DEC_inp LABEL WORD
DW OFFSET Dummy ;case adjustment
DW OFFSET DEC_val ;validate input
DW OFFSET DEC_rec ;recalculate total
DW OFFSET DEC_upd ;update input string
DW (DEC_Y * 256) + DEC_X ;location
DW OFFSET DEC_base ;input base
DW DEC_MAX ;input maximum
DW ? ;input length
DW ? ;input pointer
;--- character input data
CHR_X EQU 2
CHR_Y EQU 8
CHR_MAX EQU 4
CHR_inp LABEL WORD
DW OFFSET Dummy ;case adjustment
DW OFFSET Dummy ;validate input
DW OFFSET CHR_rec ;recalculate total
DW OFFSET CHR_upd ;update input string
DW (CHR_Y * 256) + CHR_X ;location
DW OFFSET CHR_base ;input base
DW CHR_MAX ;input maximum
DW ? ;input length
DW ? ;input pointer
;--- key commands
Commands LABEL WORD
DW 4B00H, OFFSET Cmd_Left
DW 4D00H, OFFSET Cmd_Right
DW 4700H, OFFSET Cmd_Home
DW 4F00H, OFFSET Cmd_End
DW 4800H, OFFSET Cmd_Prev
DW 0F00H, OFFSET Cmd_Prev
DW 5000H, OFFSET Cmd_Next
DW 0F09H, OFFSET Cmd_Next
DW 0E08H, OFFSET Cmd_Bksp
DW 5300H, OFFSET Cmd_Delete
DW 0E7FH, OFFSET Cmd_Erase
DW 0
;--- TSR data
TSR_ID1 EQU 4241H
TSR_ID2 EQU 5345H
TSR_SHIFT EQU KEY_CTRL OR KEY_ALT ;shift keys
TsrUsr LABEL BYTE
DB 1, OFFSET Segment
DB 0
TsrKey LABEL WORD
DW 3000H, OFFSET Base ;hot key, ALT-B
DW 0
;--- window text
tex1 DB 'BASE',0
tex2 DB 'Hex',0
tex3 DB 'Decimal',0
tex4 DB 'Character',0
;========================================
; Dummy routine.
Dummy PROC NEAR
clc
ret
ENDP
;========================================
; Hex routines.
;=== adjust
HEX_adj PROC NEAR
cmp al, 'a' ;lower limit
jb hexadj1
cmp al, 'z' ;upper limit
ja hexadj1
and al, NOT 20H ;convert to upper case
hexadj1 ret
ENDP
;=== validate
HEX_val PROC NEAR
cmp al, '0' ;lower number limit
jb hexval1
cmp al, '9' ;upper number limit
jbe hexval2
hexval1 cmp al, 'A' ;lower letter limit
jb hexval3
cmp al, 'F' ;upper letter limit
ja hexval3
hexval2 clc
ret
hexval3 stc
ret
ENDP
;=== recalculate, Out: DX:AX= total
HEX_rec PROC NEAR
push bx
mov ax, OFFSET HEX_base ;hex input buffer
mov di, ax
add di, [bx+inplen] ;point to byte past end
mov BYTE [di], 0 ;store NUL
mov cx, 16 ;base
call Str2Num ;convert to string
pop bx
ret
ENDP
;=== update, set HEX_base and inplen, In: DX:AX= total
HEX_upd PROC NEAR
push bx
mov cx, 16 ;base
mov si, OFFSET HEX_base ;input buffer
mov bx, si
call Num2Str ;convert to string
pop bx
mov HEX_inp + inplen, ax ;store length
ret
ENDP
;========================================
; Decimal routines.
;=== validate
DEC_val PROC NEAR
cmp al, '0' ;lower limit
jb decval1
cmp al, '9' ;upper limit
ja decval1
clc
ret
decval1 stc
ret
ENDP
;=== recalculate, Out: DX:AX= total
DEC_rec PROC NEAR
push bx
mov ax, OFFSET DEC_base ;input buffer
mov di, ax
add di, [bx+inplen] ;point to byte past end
mov BYTE [di], 0 ;store NUL
mov cx, 10 ;base
call Str2Num ;convert to string
jnc decrec1 ;exit if okay
mov ax, 0FFFFH ;max value FFFFFFFF
mov dx, ax ;
decrec1 pop bx
ret
ENDP
;=== update, set DEC_base and inplen, In: DX:AX= total
DEC_upd PROC NEAR
push bx
mov cx, 10 ;base
mov si, OFFSET DEC_base ;input buffer
mov bx, si
call Num2Str ;convert to string
pop bx
mov DEC_inp + inplen, ax ;store length
ret
ENDP
;========================================
; Character routines.
;=== recalculate, Out: DX:AX= total
CHR_rec PROC NEAR
cld
sub ax, ax ;zero total
mov dx, ax ;
mov cx, CHR_inp + inplen ;get length
jcxz chrrec2 ;exit if zero bytes
mov si, OFFSET CHR_base ;input buffer
chrrec1 mov dh, dl ;
mov dl, ah ;-- shift 32 bit value
mov ah, al ;
lodsb ;load lower byte
loop chrrec1 ;loop for each character
chrrec2 ret
ENDP
;=== update, set CHR_base and inplen, In: DX:AX= total
CHR_upd PROC NEAR
cld ;forward direction
mov di, OFFSET CHR_base ;input buffer
mov cx, 4 ;number of characters
;--- skip preceding zeros
chrupd1 or dh, dh ;check if zero
jnz chrupd2 ;exit if not
mov dh, dl ;
mov dl, ah ;-- shift 32 bit value
mov ah, al ;
loop chrupd1 ;loop until all bytes
chrupd2 mov CHR_inp + inplen, cx ;store length
jcxz chrupd4 ;exit if no bytes
chrupd3 mov [di], dh ;store upper byte
inc di ;increment pointer
mov dh, dl ;
mov dl, ah ;-- shift 32 bit value
mov ah, al ;
loop chrupd3 ;loop until all bytes
chrupd4 ret
ENDP
;========================================
; Left.
Cmd_Left PROC NEAR
cmp WORD [bx+inpptr], 0 ;check if at edge
je cmdlef1 ;exit if so
dec WORD [bx+inpptr] ;move left
cmdlef1 clc
ret
ENDP
;========================================
; Right.
Cmd_Right PROC NEAR
mov ax, [bx+inplen] ;load bytes in buffer
cmp ax, [bx+inpmax] ;check if past edge
jne cmdrig1
dec ax ;real edge
cmdrig1 cmp ax, [bx+inpptr] ;check if at edge
je cmdrig2 ;exit if so
inc WORD [bx+inpptr] ;move right
cmdrig2 clc
ret
ENDP
;========================================
; Home.
Cmd_Home PROC NEAR
mov WORD [bx+inpptr], 0 ;move home
clc
ret
ENDP
;========================================
; End.
Cmd_End PROC NEAR
mov ax, [bx+inpmax] ;maximum input
dec ax ;real edge
cmp ax, [bx+inplen] ;check if filled
jbe cmdend1 ;exit if so, use this edge
mov ax, [bx+inplen] ;use end of bytes
cmdend1 mov [bx+inpptr], ax ;move end
ret
clc
ENDP
;========================================
; Previous.
Cmd_Prev PROC NEAR
sub input, 1 ;decrement index
jnc cmdpre1 ;exit if okay
mov input, 2 ;last index
cmdpre1 stc
ret
ENDP
;========================================
; Next.
Cmd_Next PROC NEAR
inc input ;increment index
cmp input, 2 ;check if past end
jbe cmdnex1 ;exit if okay
mov input, 0 ;restart with first
cmdnex1 stc
ret
ENDP
;========================================
; Backspace.
Cmd_Bksp PROC NEAR
cmp WORD [bx+inpptr], 0 ;check if at edge
je cmdbks1 ;exit if so
dec WORD [bx+inpptr] ;move left
call Delete ;delete
cmdbks1 stc
ret
ENDP
;========================================
; Delete.
Cmd_Delete PROC NEAR
call Delete ;delete character
stc
ret
ENDP
;========================================
; Erase.
Cmd_Erase PROC NEAR
mov empty, 0 ;zero all inputs
stc
ret
ENDP
;========================================
; Delete a character from a buffer.
;
; In: BX= input pointer.
Delete PROC NEAR
mov cx, [bx+inplen] ;load bytes
mov si, [bx+inpptr] ;load pointer
sub cx, si ;get bytes to shift
jz delete1 ;jump if at end
dec cx ;delete this byte
add si, [bx+inpbas] ;point to byte to delete
mov di, si
inc si ;point to next byte
cld
rep
movsb ;shift bytes left
dec WORD [bx+inplen] ;reduce length
jnz delete1 ;exit if not zero
mov empty, 0 ;erase all inputs
delete1 ret
ENDP
;========================================
; Insert a character into a buffer.
;
; In: AL= character; BX= input pointer.
Insert PROC NEAR
mov dx, [bx+inpmax] ;maximum input
mov cx, [bx+inplen] ;current bytes
mov si, [bx+inpbas] ;input buffer
mov di, [bx+inpptr] ;current pointer
add di, si ;current byte
cmp dx, cx ;check if buffer full
je insert1 ;skip shift if so
push di
add si, cx ;point to byte past end
mov di, si
dec si ;point to last byte
sub cx, [bx+inpptr] ;bytes to shift
std
rep
movsb ;shift bytes to right
inc WORD [bx+inplen] ;increment length
pop di
;--- store character
insert1 cld
stosb ;store character
dec dx ;last location
cmp dx, [bx+inpptr] ;check if at end
je insert2
inc WORD [bx+inpptr] ;increment pointer
insert2 mov empty, 1 ;set non-empty flag
ret
ENDP
;========================================
; Display a buffer.
;
; In: SI= input pointer; BX= current
; input pointer.
Display PROC NEAR
push bx
;--- set color
mov al, atr4 ;non-active attribute
cmp si, bx ;check if this is active input
jne displa1
mov al, atr5 ;active attribute
displa1 call AtrSet ;set color
;--- clear to end of buffer or whole buffer
mov di, [si+inpbas] ;input buffer
mov cx, [si+inpmax] ;maximum characters
sub dx, dx ;empty length
cmp empty, 0 ;check if empty
je displa2 ;jump if so
mov dx, [si+inplen] ;length
add di, dx ;byte past end
sub cx, dx ;bytes after end
displa2 mov al, ' ' ;space
cld
rep
stosb ;fill with spaces
mov [si+inplen], dx ;save length, might be reset
;--- display
mov ax, base_xy ;base coordinates
add ax, [si+locate] ;input location
call CurMov ;position cursor
mov ax, [si+inpbas] ;buffer address
mov cx, [si+inpmax] ;buffer size
call WrtStrc ;display
pop bx
ret
ENDP
;========================================
; Move the cursor to the current
; location.
;
; In: BX= input pointer.
Cursor PROC NEAR
push bx
;--- check if pointer is past end
mov ax, [bx+inpmax] ;buffer size
dec ax ;end location
cmp ax, [bx+inplen] ;check if buffer filled
jbe cursor1
mov ax, [bx+inplen] ;use end of bytes
cursor1 cmp ax, [bx+inpptr] ;check if pointer is okay
jae cursor2
mov [bx+inpptr], ax ;fix pointer
;--- position cursor
cursor2 mov ax, base_xy ;base address
add ax, [bx+locate] ;start of input
add ax, [bx+inpptr] ;current location
call CurMov ;position cursor
pop bx
ret
ENDP
;========================================
; Load the window coordinates.
Coords PROC NEAR
mov bx, base_xy ;upper left
mov cx, bx
add cx, ((ROWS-1)*256)+(COLS-1) ;lower right
mov dx, ds ;current segment
mov ax, OFFSET screen ;screen save area
ret
ENDP
;========================================
; Main routine.
Base PROC NEAR
mov empty, 0 ;no input
mov tot_lo, 0 ;zero total
mov tot_hi, 0 ;
;--- initialize video
call VidInit ;initialize video routines
jnc base1
jmp baseB
base1 call ModDim ;current columns and rows
sub al, COLS + 1 ;starting column
mov ah, 1 ;starting row
mov base_xy, ax ;save save it
;--- save screen area
call CurPos ;get cursor position
push ax ;save on stack
call Coords ;load coordinates
call ScrGet ;save
;--- draw screen
mov al, atr2
call AtrSet
call Coords
call ScrClr
mov al, atr1
call AtrSet
call Coords
call DrwBox
mov al, atr6
call AtrSet
mov ax, base_xy
add al, 5
call CurMov
mov ax, OFFSET tex1
call WrtStr
mov al, atr3
call AtrSet
mov ax, base_xy
add ax, 0102H
call CurMov
mov ax, OFFSET tex2
call WrtStr
mov ax, base_xy
add ax, 0402H
call CurMov
mov ax, OFFSET tex3
call WrtStr
mov ax, base_xy
add ax, 0702H
call CurMov
mov ax, OFFSET tex4
call WrtStr
;=== loop until escape
;--- update strings if some input
base2 mov bx, input ;input record index
shl bx, 1 ;times two
mov bx, [inputs + bx] ;load input record
cmp empty, 0 ;check if empty
je base3 ;skip update if so
mov ax, tot_lo
mov dx, tot_hi
call HEX_inp + update ;update hex number
mov ax, tot_lo
mov dx, tot_hi
call DEC_inp + update ;update decimal number
mov ax, tot_lo
mov dx, tot_hi
call CHR_inp + update ;update characters
;--- redisplay all inputs
base3 mov si, OFFSET HEX_inp
call Display ;display hex number
mov si, OFFSET DEC_inp
call Display ;display decimal number
mov si, OFFSET CHR_inp
call Display ;display characters
base4 call Cursor ;current cursor location
;--- wait for keystroke
base5 sub ah, ah ;read key function
int 16H ;execute
cmp al, 27 ;check if exit
je baseA ;jump if so
mov si, OFFSET Commands ;command table
base6 cmp WORD [si], 0 ;check if end of table
je base8
cmp WORD [si], ax ;check if key matches
je base7
add si, 4 ;next entry
jmps base6 ;loop back
base7 call WORD [si + 2] ;call command
jnc base4 ;jump if cursor movement only
jmps base9 ;jump if recalculate and display
;--- insert character
base8 or al, al ;check extended key
jz base5 ;skip if so
call WORD [bx+adjust] ;adjust character (make upper case)
call WORD [bx+valid] ;validate character
jc base5 ;skip if invalid
call Insert ;insert into buffer
base9 call WORD [bx+recalc] ;recalculate total
mov tot_lo, ax ;save low word
mov tot_hi, dx ;save high word
jmp base2
;=== finished
;--- restore screen area
baseA call Coords ;load coordinates
call ScrPut ;restore
pop ax
call CurMov ;restore cursor
baseB ret
ENDP
;========================================
; Resident query routine. Return the
; segement to uninstall.
Segment PROC NEAR
mov dx, ds
ret
ENDP
;========================================
; Uninitialized data.
ORG_FIX EQU $
base_xy LABEL WORD ;base x and y coordinates
ORG +2
empty LABEL BYTE ;zero if no input
ORG +1
tot_lo LABEL WORD ;low word of total
ORG +2
tot_hi LABEL WORD ;high word of total
ORG +2
screen LABEL BYTE ;screen save area
ORG +(ROWS * COLS * 2)
HEX_base LABEL BYTE ;hex i/o buffer
ORG +(HEX_MAX+1)
DEC_base LABEL BYTE ;decimal i/o buffer
ORG +(DEC_MAX+1)
CHR_base LABEL BYTE ;character i/o buffer
ORG +(CHR_MAX+1)
TSR_END
ORG ORG_FIX
;========================================
; Transient data.
banner DB 13,10,'BASE Version 1.00 By Eric Tauck',0
okay DB 13,10,'Base installed, press ALT-CTL-B to invoke',0
uninst DB 13,10,'Base removed from memory',0
error1 DB 13,10,'Parameter error, run BASE ? for help',0
error2 DB 13,10,'Error: Already installed',0
error3 DB 13,10,'Error: Not installed',0
error4 DB 13,10,'Error: Cannot uninstall',0
help DB 13,10
DB 'Usage: BASE [option]',13,10
DB 13,10
DB ' /R resident mode',13,10
DB ' /U uninstall'
DB 0
colors DB ATR1_COL, ATR2_COL, ATR3_COL, ATR4_COL, ATR5_COL, ATR6_COL
;========================================
; Installation.
;--- transient library files
install INCLUDE 'library\start.asm'
INCLUDE 'library\case2.asm'
INCLUDE 'library\memory.asm'
INCLUDE 'library\message1.asm'
INCLUDE 'library\intr.asm'
INCLUDE 'library\parms.asm'
INCLUDE 'library\video2.asm'
INCLUDE 'library\video8.asm'
;--- determine attributes to use
call VidCol ;check if color adapter
jnc instal1 ;skip if not
mov si, OFFSET colors
mov di, OFFSET atr1
mov cx, 6
cld
rep
movsb ;copy color attributes to atr1-6
;--- check if already installed
instal1 sub si, si ;zero if not installed
Query 1 ;query
jc instal2 ;skip if not installed
mov si, dx ;save segment
;--- check parameters
instal2 call ParGet ;get parameter
jc instal5
push ax
mov ax, OFFSET banner ;banner
call MesPutL ;display only if parameters
pop ax
push ax
call StrUpr ;convert to upper case
pop bx
mov ax, [bx] ;load first two bytes
cmp al, '?'
je instal4
cmp ah, '?'
je instal4
cmp ax, '/H'
je instal4
cmp ax, '/R'
je instal7
cmp ax, '/U'
je instal8
;=== error in parameters
mov ax, OFFSET error1
instal3 call MesPutL ;display error message
mov ax, 4CFFH ;exit function with error
int 21H ;execute
;--- display help
instal4 mov ax, OFFSET help ;help message
jmps instal3
;--- run non-resident
instal5 call Base ;run program
instal6 mov ax, 4C00H ;exit function
int 21H ;execute
;--- make resident
instal7 mov ax, OFFSET error2 ;possible error message
or si, si ;check if already installed
jnz instal3 ;jump if so
mov ax, OFFSET okay
call MesPutL ;display installed message
Trap21 ;hook interrupt 21
Trap16 ;hook interrupt 16
Keep ;make resident
;--- uninstall
instal8 mov ax, OFFSET error3 ;possible error message
or si, si ;check resident
jz instal3 ;jump if not
Okay16 si ;verify
jne instal9
Okay21 si ;verify
jne instal9
Free16 si ;release interrupt 16
Free21 si ;release interrupt 21
mov ax, si
call MemRel ;release memory
mov ax, OFFSET uninst
call MesPutL ;display message
jmp instal6
instal9 mov ax, OFFSET error4 ;error message
jmp instal3